#include "ThreadPool.hpp"
#include "Task.hpp"
#include <ctime>
#include <thread>

// 如何对一个线程进行封装, 线程需要一个回调函数(支持lambda)自行实现
// class tread{
// };

int main()
{
    prctl(PR_SET_NAME, "master");

    const string operators = "+/*/%";
    // unique_ptr<ThreadPool<Task> > tp(new ThreadPool<Task>());
    unique_ptr<ThreadPool<Task> > tp(ThreadPool<Task>::getInstance());
    tp->start();

    srand((unsigned long)time(nullptr) ^ getpid() ^ pthread_self());
    // 派发任务的线程
    while(true)
    {
        int one = rand()%50;
        int two = rand()%10;
        char oper = operators[rand()%operators.size()];
        Log() << "主线程派发计算任务: " << one << oper << two << "=?" << "\n";
        Task t(one, two, oper);
        tp->push(t);
        sleep(1);
    }
}





















































// /*threadpool.h*/
// /* 线程池:
// * 一种线程使用模式。线程过多会带来调度开销，进而影响缓存局部性和整体性能。而线程池维护着多个线
// 程，等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够
// 保证内核的充分利用，还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络
// sockets等的数量。
// * 线程池的应用场景：
// * 1. 需要大量的线程来完成任务，且完成任务的时间比较短。 WEB服务器完成网页请求这样的任务,使用线
// 程池技术是非常合适的。因为单个任务小，而任务数量巨大，你可以想象一个热门网站的点击次数。 但对于长时间的任
// 务,比如一个Telnet连接请求,线程池的优点就不明显了。因为Telnet会话时间比线程的创建时间大多了。
// *  2. 对性能要求苛刻的应用，比如要求服务器迅速响应客户请求。
// * 3. 接受突发性的大量请求，但不至于使服务器因此产生大量线程的应用。突发性大量客户请求，在没有线
// 程池情况下，将产生大量线程，虽然理论上大部分操作系统线程数目最大值不是问题，短时间内产生大量线程可能使内
// 存到达极限，出现错误.
// * 线程池的种类：
// * 线程池示例：
// *  1. 创建固定数量线程池，循环从任务队列中获取任务对象，
// *  2. 获取到任务对象后，执行任务对象中的任务接口
// */
// /*threadpool.hpp*/

// #ifndef __M_TP_H__
// #define __M_TP_H__
// #include <iostream>
// #include <queue>
// #include <pthread.h>
// #include <unistd.h>
// #define MAX_THREAD 5
// typedef bool (*handler_t)(int);
// class ThreadTask
// {
// private:
//     int _data;
//     handler_t _handler;

// public:
//     ThreadTask() : _data(-1), _handler(NULL) {}
//     ThreadTask(int data, handler_t handler)
//     {
//         _data = data;
//         _handler = handler;
//     }
//     void SetTask(int data, handler_t handler)
//     {
//         _data = data;
//         _handler = handler;
//     }
//     void Run()
//     {
//         _handler(_data);
//     }
// };
// class ThreadPool
// {
// private:
//     int _thread_max;
//     int _thread_cur;
//     bool _tp_quit;
//     std::queue<ThreadTask *> _task_queue;
//     pthread_mutex_t _lock;
//     pthread_cond_t _cond;

// private:
//     void LockQueue()
//     {
//         pthread_mutex_lock(&_lock);
//     }
//     void UnLockQueue()
//     {
//         pthread_mutex_unlock(&_lock);
//     }
//     void WakeUpOne()
//     {
//         pthread_cond_signal(&_cond);
//     }
//     void WakeUpAll()
//     {
//         pthread_cond_broadcast(&_cond);
//     }
//     void ThreadQuit()
//     {
//         _thread_cur--;
//         UnLockQueue();
//         pthread_exit(NULL);
//     }
//     void ThreadWait()
//     {
//         if(_tp_quit)
//         {
//             ThreadQuit();
//         }
//         pthread_cond_wait(&_cond, &_lock);
//     }
//     bool IsEmpty()
//     {
//         return _task_queue.empty();
//     }
//     static void *thr_start(void *arg)
//     {
//         ThreadPool *tp = (ThreadPool *)arg;
//         while (1)
//         {
//             tp->LockQueue();
//             while (tp->IsEmpty())
//             {
//                 tp->ThreadWait();
//             }
//             ThreadTask *tt;
//             tp->PopTask(&tt);
//             tp->UnLockQueue();
//             tt->Run();
//             delete tt;
//         }
//         return NULL;
//     }

// public:
//     ThreadPool(int max = MAX_THREAD) : _thread_max(max), _thread_cur(max),
//                                        _tp_quit(false)
//     {
//         pthread_mutex_init(&_lock, NULL);
//         pthread_cond_init(&_cond, NULL);
//     }
//     ~ThreadPool()
//     {
//         pthread_mutex_destroy(&_lock);
//         pthread_cond_destroy(&_cond);
//     }
//     bool PoolInit()
//     {
//         pthread_t tid;
//         for (int i = 0; i < _thread_max; i++)
//         {
//             int ret = pthread_create(&tid, NULL, thr_start, this);
//             if (ret != 0)
//             {
//                 std::cout << "create pool thread error\n";
//                 return false;
//             }
//         }
//         return true;
//     }
//     bool PushTask(ThreadTask *tt)
//     {
//         LockQueue();
//         if (_tp_quit)
//         {
//             UnLockQueue();
//             return false;
//         }
//         _task_queue.push(tt);
//         WakeUpOne();
//         UnLockQueue();
//         return true;
//     }
//     bool PopTask(ThreadTask **tt)
//     {
//         *tt = _task_queue.front();
//         _task_queue.pop();
//         return true;
//     }
//     bool PoolQuit()
//     {
//         LockQueue();
//         _tp_quit = true;
//         UnLockQueue();
//         while (_thread_cur > 0)
//         {
//             WakeUpAll();
//             usleep(1000);
//         }
//         return true;
//     }
// };
// #endif
// /*main.cpp*/
// bool handler(int data)
// {
//     srand(time(NULL));
//     int n = rand() % 5;
//     printf("Thread: %p Run Tast: %d--sleep %d sec\n", pthread_self(), data, n);
//     sleep(n);
//     return true;
// }
// int main()
// {
//     int i;
//     ThreadPool pool;
//     pool.PoolInit();
//     for (i = 0; i < 10; i++)
//     {
//         ThreadTask *tt = new ThreadTask(i, handler);
//         pool.PushTask(tt);
//     }
//     pool.PoolQuit();
//     return 0;
// }

// // 懒汉模式, 线程安全
// template <typename T>
// class Singleton
// {
//     volatile static T *inst;
//     // 需要设置 volatile 关键字, 否则可能被编译器优化.
//     static std::mutex lock;

// public:
//     static T *GetInstance()
//     {
//         if (inst == NULL)
//         {
//             // 双重判定空指针, 降低锁冲突的概率, 提高性能.
//             lock.lock();
//             // 使用互斥锁, 保证多线程情况下也只调用一次 new.
//             if (inst == NULL)
//             {
//                 inst = new T();
//             }
//             lock.unlock();
//         }
//         return inst;
//     }
// };

